
  
  <template>
    <div class="project">
      <!-- 菜单栏 -->
      <div class="menu-bar" v-if="currentProject.id">
        <!-- 左对齐的元素 -->
        <div class="left-buttons">
          <input v-model="currentProject.name" placeholder="Enter Project Name" />
          <a-popover content="Settings" placement="top" trigger="hover" color="#ccc">
            <div @click="setSettings">
              <OperatorIcon name="setting" :W="16" :H="16" />
            </div>
          </a-popover>

          <a-popover content="Inspector" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="isInspectorVisible = !isInspectorVisible">
              <OperatorIcon name="<" :W="16" :H="16" />
            </div>
          </a-popover>
          <a-popover content="SetView" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="setViewer()">
              <OperatorIcon name="eye" :W="16" :H="16" />
            </div>
          </a-popover>
          <a-popover content="SaveView" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="saveView">
              <Icon name="camera1" :W="16" :H="16" />
            </div>
          </a-popover>
          <a-popover content="Save" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="saveProject">
              <Icon name="save" :W="16" :H="16" />
            </div>
          </a-popover>

          <a-popover content="Refresh" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="refreshProject">
              <OperatorIcon name="refresh" :W="16" :H="16" />
            </div>
          </a-popover>

          <a-popover content="DropSelected" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="removeNodeAndEdges">
              <Icon name="trash" :W="16" :H="16" />
            </div>
          </a-popover>
          <a-popover content="Clear" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @click="clearProject">
              <Icon name="broom" :W="16" :H="16" />
            </div>
          </a-popover>
          <a-popover content="Delete" placement="top" trigger="hover" color="#ccc">
            <div v-if="!isSetting" @mouseenter="isHoverx = true" @mouseleave="isHoverx = false" @click="deleteProject">
              <OperatorIcon name="x" :W="16" :H="16" :Fill="isHoverx ? '#ff4f4f' : '#000000'" />
            </div>
          </a-popover>

        </div>

        <!-- 右对齐的按钮 -->
        <button class="deploy-button" @click="deployAction" :disabled="deployButtonState.disable||isSetting">{{
          deployButtonState.deployText }}</button>
      </div>
      <!-- 主体部分 -->
      <div v-if="isSetting" style="width:100%;height:100%;position:relative;overflow-y:auto;">
        <ProjectSetting :projectID="setting_currentProject?.id ?? ''" :authorName="setting_currentProject?.authorName ?? ''"
          :authorID="setting_currentProject?.authorID ?? ''" :teamName="setting_currentProject?.teamName ?? ''"
          :teamID="setting_currentProject?.teamID ?? ''" :isPublic="setting_currentProject?.isPublic ?? false"
          :description="setting_currentProject?.description ?? ''" :thumbnailUrl1="lastView ?? ''" :thumbnailUrl="thumbnailUrl ?? ''"
          :saveViewUrl="saveViewUrl ?? ''" />
      </div>
      <div class="content" v-else-if="currentProject.id">

        <div class="inspector" v-if="isInspectorVisible" ref="inspectorRef" :style="{width: inspectorWidth + 'px'}">
          <div v-if="selectedNode.length > 0" style="font-family:monospace">
            <div v-for="node in selectedNode" :key="node.id" class="inspector-item">

              <div class="inspector-item1">
                <div class="insp-l">NAME: {{ node.data.name }}</div>
              </div>

              <p>ID: {{ node.id }}</p>
            </div>
          </div>
          <div v-else style="font-family:monospace">
            <p>Select nodes to see details</p>
          </div>
        </div>
        <div v-if="isInspectorVisible" class="inspector-drag" @mousedown.stop="mousedown1"></div>
        <div v-else style="width:5px;"></div>
        <!-- 其他主体部分，可以根据需求添加 -->
        <div class="editor">
          <!-- <FlowCanvas :initialData="()=>{return JSON.parse(currentProject.content)}" /> -->
          <FlowCanvas :id="currentProject.id" :key="componentKey" ref="flowCanvasInstance" class="flowcanvasgraph" :pjid="currentProject.id" />
        </div>
      </div>
    </div>
  </template>
  

  <script lang="ts">
  import { defineComponent, watch, ref, onMounted,computed,nextTick, onUnmounted,onBeforeUnmount } from 'vue';
  import { useRoute } from 'vue-router';
  import { useProjectsStore } from '../stores/projectsStore'; // 替换为你store路径
  import FlowCanvas from './FlowCanvas.vue'; // 引入FlowCanvas组件
  import ProjectSetting from './ProjectSetting.vue';
  import { initialEdges, initialNodes } from './data/initial-elements'
  import useServer from './ts/useServer';
  import { useUserStore } from '@/stores/userStore';
  import Dialog from './Dialog.vue'
import useDialog from './ts/useDialog.ts'
import { dialogMsg } from './ts/useDialog.ts'

const { confirm } = useDialog()

import { useVueFlow } from '@vue-flow/core'
import { algorithmOptions, modelOptions, languageOptions } from './flowComponents/ts/STTNode_op'
const { updateNodeData,updateNodeInternals } = useVueFlow()

import OperatorIcon from './icons/OperatorIcon.vue'
import Icon from './icons/Icon.vue'

import html2canvas from 'html2canvas'
import {message} from 'ant-design-vue'

export default defineComponent({
    name: 'Project',
    components: {
      FlowCanvas,
      ProjectSetting,
      OperatorIcon,
    Icon,
    },
    setup() {
      const projectsStore = useProjectsStore();
      const flowCanvasInstance=ref<any>(null)
      const inspectorRef = ref<any>(null);
     // console.log('projectsStore.projects',projectsStore.projects)
      const currentProject =  ref(projectsStore.projects.find(p => p.id === projectsStore.currentProjectId) || { id: '', name: '', content: {initialEdges:[], initialNodes:[]}, loaded:true });
      const setting_currentProject =  computed(()=>projectsStore.projects.find(p => p.id === projectsStore.currentProjectId) || { id: '', name: '', content: {initialEdges:[], initialNodes:[]}, loaded:true });
      function updateProjectName(){
        if (currentProject.value && projectsStore.currentProjectId) {
          projectsStore.updateProjectName(projectsStore.currentProjectId, currentProject.value.name);
        }
      };
    const selectedNode = computed(()=>flowCanvasInstance.value?.getSelectedNodes() || [])
      const isInspectorVisible = ref(true);
      const componentKey = ref(0);
      const refreshComponent = () => {
        componentKey.value += 1; // 改变 key 值以强制重新渲染
      };

      watch(() => projectsStore.currentProjectId, (newProjectId, oldProjectId) => {
        const oldPorject = projectsStore.projects.find(p => p.id === oldProjectId);
        console.log('oldProject', oldProjectId)
        isSetting.value=false
        saveViewUrl.value=''
        lastView.value=''
        if (oldPorject && oldProjectId) projectsStore.updateProjectContent(oldProjectId, oldPorject.content, true)
        if (deployTimer) {
          clearTimeout(deployTimer);
          deployTimer = null;
        }
        const project = projectsStore.projects.find(p => p.id === newProjectId);
        if (project) {
          currentProject.value = project;
          console.log('Now Project.value',currentProject.value);
          refreshComponent();
          checkDeployed(false);
        }
        else{
          if(newProjectId==null) return;
          console.log('set currentProject initialized',currentProject.value)
          currentProject.value = { id: newProjectId, name: 'New Project', content: {initialEdges, initialNodes} };
          projectsStore.projects.push(currentProject.value)
        }
      });

      const saveProject = async () => {
        console.log("currentProject.value", currentProject.value);
        if (projectsStore.currentProjectId) {
          let res1=await projectsStore.updateProjectName(projectsStore.currentProjectId,currentProject.value.name);//更新名字
          let res2=await projectsStore.networkUpdate(projectsStore.currentProjectId);//更新内容
          message.success('Save successfully!')
        }
      };
      //将currentProject.value与store中的项目同步
      const refreshProject = () => {
        const project = projectsStore.projects.find(p => p.id === projectsStore.currentProjectId);
        if (project) {
          currentProject.value = project as any;
        }
      };

      const clearProject = async () => {

        const pro_id = currentProject.value.id
        const ok = await confirm(dialogMsg(pro_id, `[NAME: ${currentProject?.value?.name ?? ''}]`, 'Are you sure to clear this Project permanently?'))
        if (ok) {
          console.log('clearProject', projectsStore.currentProjectId)
          if (projectsStore.currentProjectId) {
            flowCanvasInstance.value?.setElements([]);
            projectsStore.updateProjectContent(projectsStore.currentProjectId, { initialEdges: [], initialNodes: [] }, true)
          }
        }
      }

      const removeNodeAndEdges = () => {
        let selected_nodes=flowCanvasInstance.value?.getSelectedNodes;
        let selected_edges=flowCanvasInstance.value?.getSelectedEdges;
        console.log('removeNodes',selected_nodes)
        console.log('removeEdges',selected_edges)
        flowCanvasInstance.value?.removeEdges(selected_edges)
        flowCanvasInstance.value?.removeNodes(selected_nodes)
      }
      let deployTimer: ReturnType<typeof setTimeout> | null = null;
      const {post, postWithCallback} = useServer();
      const userStore = useUserStore();
      const deployButtonState = ref({deployText:"Deploy", disable:false});
      const deployAction = () => {
        if (deployButtonState.value.disable==true) return;
        post('createWS', {userID:userStore.currentUser, currentProject:currentProject.value.id, content:currentProject.value.content})
        deployButtonState.value.disable = false;
        if (deployTimer) {
          clearTimeout(deployTimer);
          deployTimer = null;
        }
        deployTimer = setTimeout(() => { checkDeployed() }, 2000);
      };
      const checkDeployed=(is_click:boolean=true)=>{
        deployButtonState.value.disable = false;
        postWithCallback('checkProjectRunning',{userID:userStore.currentUser, projectID:currentProject.value.id}, (response:any)=>{
          console.log(response)
          if (response.running){
            deployButtonState.value.disable = false;
            if(is_click && deployButtonState.value.deployText == "Deploy")message.info("Project has been deployed.")
            deployButtonState.value.deployText = "Redeploy";
          }else{
            deployButtonState.value.disable = false;
            deployButtonState.value.deployText = "Deploy";
          }
        })
      }
      let lastViewTimer:ReturnType<typeof setInterval>
      onMounted(() => {
        checkDeployed(false);
      });

      // 初始加载时，设置当前项目内容
      onMounted(() => {
        isInspectorVisible.value = false;//默认关闭inspector
        const project = projectsStore.projects.find(p => p.id === projectsStore.currentProjectId);
        if (project) {
          currentProject.value = project as any;
        }
      });

      const InitialData = computed(() => {
        return currentProject.value.content;
      });

      const deleteProject = async () => {
        const pro_id = currentProject.value.id
        const ok = await confirm(dialogMsg(pro_id, `[NAME: ${currentProject?.value?.name ?? ''}]`, 'Are you sure to delete this Project permanently?'))
        if (ok) {
          projectsStore.deleteProject(pro_id)
        }
      }
      //inspector拖拽相关
      const inspectorWidth = ref(260)
      let startx = 0
      let startW = 260
      const mousedown1 = (e: MouseEvent) => {
        startx = e.clientX
        startW = inspectorWidth.value
        document.addEventListener('mousemove', mousemove1)
        document.addEventListener('mouseup', mouseup1)
        e.preventDefault();
      }
      const mousemove1 = (e: MouseEvent) => {
        const offsetx = e.clientX - startx
        inspectorWidth.value = Math.min(800, Math.max(250, startW + offsetx));
      }
      const mouseup1 = () => {
        document.removeEventListener('mousemove', mousemove1)
        document.removeEventListener('mouseup', mouseup1)
      }
      const isSetting = ref(false)
      const thumbnailUrl = ref('')
      const lastView = ref('')
      const saveViewUrl=ref('')
      const setSettings = () => {
        let newSetting = !isSetting.value
        if (isSetting.value) {
          flowCanvasInstance.value?.setAddable(true)
          flowCanvasInstance.value?.setControlVisible(true)
          flowCanvasInstance.value?.setMinMapVisible(true)
          isSetting.value = newSetting
        } else {
          getlastView(()=>{
            shotScreen(false, () => {
              isSetting.value = newSetting
            })
          })
        }
      }
      //观看全屏预览
      const setViewer = (flag: boolean = false) => {
        if (!flag) {
          let flag2=isInspectorVisible.value||flowCanvasInstance.value.isAddable.value
          isInspectorVisible.value = !flag2
          flowCanvasInstance.value?.setControlVisible(!flag2)
          flowCanvasInstance.value?.setMinMapVisible(!flag2)
          flowCanvasInstance.value?.setAddable(!flag2)
          setTimeout(() => {
            setViewer(true)
          }, 1)
        } else {
          flowCanvasInstance.value?.fitView()
        }
      }

      //获取最新视图
      const getlastView = (callback:()=>void=()=>{},saveflag:string='lastView') => {
        const pane = <HTMLDivElement>document.querySelector('.vue-flow.basic-flow')
        if (pane) {
          html2canvas(pane).then((canvas:any) => {
            const imgData = canvas.toDataURL('image/png')
            let tmpImg = new Image()
            tmpImg.src = imgData
            tmpImg.onload = () => {
              if(saveflag=='lastView'){
                lastView.value = tmpImg.src
              }else if(saveflag=='saveView'){
                saveViewUrl.value = tmpImg.src
              }
              //console.log('保存视图成功',lastView.value)
              callback()
            }
          })
        }
      }
      const saveView=()=>{
        getlastView(()=>{
          message.info('save view success')
        }, 'saveView')
      }
      //获取缩略图
      const shotScreen = (flag: boolean = false, callback: () => void = () => { }) => {
        if (!flag) {
          isInspectorVisible.value = false
          flowCanvasInstance.value?.setAddable(false)
          flowCanvasInstance.value?.setControlVisible(false)
          flowCanvasInstance.value?.setMinMapVisible(false)
          flowCanvasInstance.value?.fitView()
          setTimeout(() => {
            shotScreen(true, callback)
          }, 1)
        } else {
          flowCanvasInstance.value?.fitView()
          const pane = <HTMLDivElement>document.querySelector('.vue-flow.basic-flow')
          if (!pane) return
          html2canvas(pane).then((canvas:any) => {
            const imgData = canvas.toDataURL('image/png')
            let tmpImg = new Image()
            tmpImg.src = imgData
            tmpImg.onload = () => {
              thumbnailUrl.value = tmpImg.src
              callback()
            }
          })
        }
      }
      const isHoverx = ref(false)
      return {
        saveView,
        saveViewUrl,
        getlastView,
        thumbnailUrl,
        lastView,
        setViewer,
        shotScreen,
        mousedown1,
        inspectorWidth,
        isSetting,
        setSettings,
        flowCanvasInstance,
        inspectorRef,
        currentProject,
        updateProjectName,
        isInspectorVisible,
        saveProject,
        refreshProject,
        clearProject,
        removeNodeAndEdges,
        deleteProject,
        deployAction,
        InitialData,
        componentKey,
        deployButtonState,
        algorithmOptions,
        modelOptions,
        languageOptions,
        setting_currentProject,
        isHoverx,
        selectedNode,
      };
    },
  });
  </script>
  <style scoped lang="scss">

  .project-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
  }

  .project-name-input {
    font-size: 18px;
    padding: 8px;
    border-radius: 4px;
    border: 1px solid #ccc;
    width: 100%;
  }

  .project-content {
    margin-top: 10px;
  }

  textarea {
    width: 200px;
    height: 90%;
    padding: 5px;
    border-radius: 4px;
    border: 1px solid #ccc;
    font-size: 16px;
    line-height: 1;
  }


  .project {
    width: 100%;
    height:100%;
    flex-direction: column;
    display:flex;
    margin:0;
    position:relative;
  }

  .content {
    display: flex;
    width: 100%;
   height:90%;
  }

  .inspector {
    min-width: 250px;
    background-color: #c0bcbc49;
    padding: 5px 20px;
    border-radius: 10px;
    resize: horizontal;
    /* 只允许水平拖动改变宽度 */
    overflow-y: auto;
    overflow-x: hidden;
    display:flex;
    gap:2px;
    flex-direction: column;

    .inspector-item {
      position: relative;
      overflow: hidden;
      background-color: #d5d4cd51;
      border-radius: 5px;
      padding: 0 3px;
      width: 100%;

      .inspector-item1 {
        display: flex;
        justify-content: space-between;
        height: 30px;
        position: relative;
        overflow: hidden;
      }

      .inspector-item2 {
        height: auto;
        min-height:100px;
        position: relative;
        display: flex;
        justify-content: space-between;
      }

      .inspector-item3 {
        position: relative;
        min-height:200px;
        height:auto;
         overflow: hidden;
      }
    }

    &::-webkit-scrollbar {
      width: 8px;
      /* 滚动条宽度 */
    }

    &::-webkit-scrollbar-track {
      background: #f1f1f1;
      /* 滚动条轨道颜色 */
      border-radius: 8px;
    }

    &::-webkit-scrollbar-thumb {
      background: #ffbbbb;
      /* 滚动条滑块颜色 */
      border-radius: 8px;
    }

    &::-webkit-scrollbar-thumb:hover {
      background: #ff4f4f;
      /* hover 时高亮 */
    }
  }

  .insp-l {
    height: 100%;
    font-size: 14px;
    font-weight: 600;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    width: 130px;
    overflow: hidden;
    white-space: nowrap;
    position:relative;
  }

  .insp-r {
    flex: 1;
    height: 100%;
    position:relative;
    display:flex;

    input[type="text"],
    input[type="number"],
    textarea,
    select {
      padding: 4px 6px;
      border-radius: 4px;
      border: 1px solid #ccc;
      font-family: monospace;
      font-size: 14px;
      box-sizing: border-box;
      transition: border-color 0.2s ease, box-shadow 0.2s ease;
    }

    input:focus,
    textarea:focus,
    select:focus {
      border-color: #007bff;
      box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
      outline: none;
    }

    input[type="text"],
    input[type="number"] {
      white-space: nowrap;
      /* 禁止换行 */
      text-overflow: ellipsis;
      /* 超长显示省略号 */
    }

    textarea {
      white-space: pre-wrap;
      overflow-wrap: break-word;
      resize: horizontal;
      overflow-y: auto;
      overflow-x: hidden;
    }

    input[type="checkbox"] {
      width: 16px;
      height: 16px;
    }
    button{
      width:100px;
    }
  }

  .inspector-drag {
    width: 6px;
    height: 100%;
    cursor: ew-resize;
    background: rgba(0, 0, 0, 0.1);

    &:hover {
      background: rgba(0, 0, 0, 0.3);
    }
  }

  .editor {
    flex: 1;
    overflow-y:auto
  }

  input {
    padding: 8px;
    margin:3px auto;
    border: 1px solid #ccc;
    border-radius: 5px;
    width: 200px;
  }

  .menu-bar {
    display: flex;
    align-items: center;
    background: #f8f8f8;
    padding: 5px;
    border-bottom: 2px solid #ddd;
    gap: 10px;
    min-height: 30px;
    /* 让元素之间有一定间距 */
  }

  /* 左侧按钮组 */
  .left-buttons {
    display: flex;
    align-items: center;
    gap: 5px;
    .opbtn{
      width:32px;
      height:32px;
      display:flex;
      justify-content: center;
      align-content: center;
    }
  }

  /* 右侧特殊按钮 */
  .deploy-button {
    margin-left: auto;
    /* 让它推送到最右边 */
    background-color: #ffbbbb;
    color: rgb(0, 0, 0);
    padding: 8px 30px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
  }

  .deploy-button:hover {
    background-color: #ff4f4f;
    color: rgb(255, 255, 255);
  }

  /* 通用按钮样式 */
  button {
    padding: 8px 12px;
    border: none;
    border-radius: 5px;
    background-color: #cacaca;
    color: rgb(0, 0, 0);
    cursor: pointer;
    transition: background 0.3s ease;
  }

  button:hover {
    background-color: #007bff;
    color: rgb(255, 255, 255);
  }

  .deploy-button[disabled] {
    background-color: #ccc;
    cursor: not-allowed;
  }

  button:disabled {
    cursor: not-allowed;
    opacity: 0.5;
    background-color: #ccc;
  }

  button:disabled:hover {
    background-color: #ccc;
  }
</style>